/* GB2312 Encoding */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : Servo.h
  - Author        : liuzhihua (liuzhihuawy@163.com)
  - Update date   : 2023.04.22
  -	Brief         : Servo Motor Driver
  - Version       : v1.0
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                       Note
  * ------------   ---------------   ----------------------------------
  *  2023.04.22       liuzhihua                   Create file          
***/

#ifndef _SERVO_H_
#define _SERVO_H_
#ifdef  __cplusplus
    extern "C" {
#endif
/*-----------------------------------------------------------------------
|                               INCLUDES                                |
-----------------------------------------------------------------------*/
#include <stdint.h>
#include "tim.h"

/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/

typedef struct Servo_StructTypedef
{
  uint8_t enable;
	TIM_HandleTypeDef *htim;
  uint8_t channel;
  uint16_t zero;
	uint16_t maxValue;
  uint16_t minValue;
  uint16_t angleRange;
}Servo_t;

#define ServoGetCompare(hse) __HAL_TIM_GET_COMPARE((hse)->htim, (hse)->channel)
#define ServoSetCompare(hse, value) __HAL_TIM_SET_COMPARE((hse)->htim, (hse)->channel, value)

#define ServoEnable(hse) do{HAL_TIM_PWM_Start((hse)->htim, (hse)->channel);(hse)->enable = 1;}while(0)
#define ServoDisable(hse) do{HAL_TIM_PWM_Stop((hse)->htim, (hse)->channel);(hse)->enable = 0;}while(0)

#define ServoGetPeriod(hse) __HAL_TIM_GET_AUTORELOAD((hse)->htim)
#define ServoGetPrescaler(hse) ((hse)->htim->Instance->PSC)
/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/
#define ServoStartAngleDuty 0.025
#define ServoAngle2Value(hservo, angle) (uint32_t)((float)ServoGetPeriod(hservo)/(hservo)->angleRange/10 * (angle)+0.5)
#define ServoValue2Angle(hservo, value) (float)((hservo)->angleRange*10.0/ServoGetPeriod(hservo) * (value))

void ServoInit(Servo_t *hservo, TIM_HandleTypeDef *htim, uint8_t channel,
                uint16_t AngleRange, uint16_t min, uint16_t max);
void ServoStart(Servo_t *hservo);
void ServoStop(Servo_t *hservo);
void ServoWrite(Servo_t *hservo, float angle);
void ServoMove(Servo_t *hservo, float angle);
float ServoRead(Servo_t *hservo);
void ServoWriteValue(Servo_t *hservo, uint16_t value);
void ServoMoveValue(Servo_t *hservo, int value);
uint16_t ServoReadValue(Servo_t *hservo);

  // void      (*write)      (float);
  // float     (*read)       (void);
  // void      (*writeValue) (uint16_t);
  // uint16_t  (*readValue)  (void);




#ifdef __cplusplus
	}
#endif
#endif
